﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Linq;

namespace RedFoxSpamKiller
{
  public partial class Form1 : Form
  {
    SpamDatabase spamDatabase;
    WebBrowserImpl webBrowserImpl;

    /// <summary>
    /// Initializes a new instance of the <see cref="Form1"/> class.
    /// </summary>
    public Form1()
    {
      InitializeComponent();
      webBrowserImpl = new WebBrowserImpl(this.webBrowser1);
    }

    const int CHECKBOX_COLUMN = 0;
    const int TITLE_COLUMN=1;
    const int LINK_COLUMN=2;

    /// <summary>
    /// Handles the Click event of the btnCheck control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    private void btnCheck_Click(object sender, EventArgs e)
    {
      if (!checkIECookies())
      {
        tabControl1.SelectedIndex = 1;
        return;
      }

      DisableAllControls();

      toolStripProgressBar1.Minimum = 0;
      toolStripProgressBar1.Maximum = 100;
      toolStripProgressBar1.Step = 1;
      toolStripProgressBar1.Value = 0;

      setStatusMessage("正在進行檢查中...");

      var worker = new QueuedBackgroundWorker();
      worker.RunAsync<BackgroundWorker, int, List<Post>>(doCheck, 0, doCheck_ProgressChanged, doCheck_RunWorkerCompleted );
    }

    private void DisableAllControls()
    {
      btnCheck.Enabled = false;
      btnDelete.Enabled = false;
      numericUpDown1.Enabled = false;
      chkBoxNotice.Enabled = false;
    }

    /// <summary>
    /// 刪除按鈕的事件處理
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    /// <returns></returns>
    private void btnDelete_Click(object sender, EventArgs e)
    {
      if (MessageBox.Show("請確定你已經使用IE登入過，否則會無法進行刪除。是否繼續?",
          this.Text,
          MessageBoxButtons.YesNo) == DialogResult.No)
        return;
      setStatusMessage("正在進行刪除...");

      DisableAllControls();

      toolStripProgressBar1.Minimum = 0;
      toolStripProgressBar1.Step = 1;
      toolStripProgressBar1.Value = 0;
      dataGridView1.SuspendLayout();

      List<DataGridViewRow> selectedRows = GetSelectedRows();
      toolStripProgressBar1.Maximum = selectedRows.Count;

      var worker = new QueuedBackgroundWorker();
      worker.RunAsync<BackgroundWorker, List<DataGridViewRow>, Dictionary<string,int>>(doDelete, selectedRows, doDelete_ProgressChanged, doDelete_RunWorkerCompleted);
    }

    /// <summary>
    /// Gets the selected rows from datagridview.
    /// </summary>
    /// <returns></returns>
    private List<DataGridViewRow> GetSelectedRows()
    {
      List<DataGridViewRow> selectedRows = new List<DataGridViewRow>();
      foreach (DataGridViewRow row in dataGridView1.Rows)
      {
        if (Convert.ToBoolean(row.Cells[CHECKBOX_COLUMN].Value) == true)
        {
          selectedRows.Add(row);
        }
      }
      return selectedRows;
    }

    /// <summary>
    /// Handles the Click event of the btnSaveSpamDatabase control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    private void btnSaveSpamDatabase_Click(object sender, EventArgs e)
    {
      spamDatabase.reload(textSpams.Lines);
      spamDatabase.save();

      fillTextSpams(); // reload again.
      setStatusMessage(String.Format("於 {0} {1} 存檔完成。", DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString()));
    }

    /// <summary>
    /// Sets the status message.
    /// </summary>
    /// <param name="msg">The MSG.</param>
    private void setStatusMessage(string msg)
    {
      toolStripStatusLabel1.Text = msg;
    }

    /// <summary>
    /// Fills the textspams.
    /// </summary>
    private void fillTextSpams()
    {
      StringBuilder sb = new StringBuilder();
      textSpams.Text = String.Join(Environment.NewLine, spamDatabase.SpamWords);
    }

    /// <summary>
    /// Handles the Load event of the Form1 control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    private void Form1_Load(object sender, EventArgs e)
    {
      try
      {
        spamDatabase = SpamDatabase.getInstance();
      }
      catch (Exception ex)
      {
        MessageBox.Show(ex.Message);
        return;
      }
      fillTextSpams();
      btnDelete.Enabled = false;
    }

    /// <summary>
    /// Does the spam check.
    /// </summary>
    private void doSpamCheck()
    {
      // Check title in spam database
      foreach (DataGridViewRow row in dataGridView1.Rows)
      {
        // 將符合的列標示為可以刪除
        if (spamDatabase.match(row.Cells[TITLE_COLUMN].Value.ToString()))
          row.Cells[CHECKBOX_COLUMN].Value = 1;
      }
    }

    /// <summary>
    /// Does the check.
    /// </summary>
    /// <param name="bk">The bk.</param>
    /// <param name="notUsed">The not used.</param>
    /// <returns></returns>
    private List<Post> doCheck(BackgroundWorker bk, int notUsed)
    {
      // Check RSS feed
      var posts = Forum.CheckRSSFeed(numericUpDown1.Value);

      bk.ReportProgress(100);

      return posts;
    }

    /// <summary>
    /// Handle progresschanged event.
    /// </summary>
    /// <param name="progressPercentage">The progress percentage.</param>
    private void doCheck_ProgressChanged(int progressPercentage)
    {
      toolStripProgressBar1.Value = progressPercentage;
    }

    /// <summary>
    /// handle workercompleted event.
    /// </summary>
    /// <param name="result">The result.</param>
    /// <param name="e">The e.</param>
    private void doCheck_RunWorkerCompleted(List<Post> result, Exception e)
    {
      // Generate list and set the list as grid's data source.
      bindingSource1.DataSource = result;

      dataGridView1.SuspendLayout();

      // Insert a checkbox column
      dataGridView1.DataSource = null;
      dataGridView1.Columns.Clear();
      DataGridViewCheckBoxColumn newColumn = new DataGridViewCheckBoxColumn();
      newColumn.HeaderText = "選擇";
      newColumn.FalseValue = 0;
      newColumn.TrueValue = 1;

      DataGridViewLinkColumn linkColumn = new DataGridViewLinkColumn();
      linkColumn.HeaderText = "連結";
      linkColumn.DataPropertyName = "Link";

      dataGridView1.DataSource = bindingSource1;
      var origLinkColumn = dataGridView1.Columns[1];
      dataGridView1.Columns.Insert(0, newColumn);
      dataGridView1.Columns.Insert(2, linkColumn);
      dataGridView1.Columns.Remove(origLinkColumn);
      dataGridView1.ClearSelection();
      doSpamCheck();

      dataGridView1.ResumeLayout();
      btnCheck.Enabled = true;
      btnDelete.Enabled = true;
      numericUpDown1.Enabled = true;
      chkBoxNotice.Enabled = true;
      btnDelete.Enabled = true;
      setStatusMessage(String.Format("檢查於 {0} {1}。", DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString()));
    }

    /// <summary>
    /// Does the delete.
    /// </summary>
    /// <param name="bw">The bw.</param>
    /// <param name="selectedRows">The selected rows.</param>
    /// <returns></returns>
    private Dictionary<string, int> doDelete(BackgroundWorker bw, List<DataGridViewRow> selectedRows)
    {
      Int32 selectedRowCount = selectedRows.Count;

      var statistics = new Dictionary<string, int>();
      for (int i = 0; i < selectedRowCount; i++)
      {
        var link = selectedRows[i].Cells[LINK_COLUMN].Value.ToString();
        // Remove the article
        Forum.DeletePost(Forum.GenerateRemoveLink(link));

        // add into spam database
        spamDatabase.addWord(selectedRows[i].Cells[TITLE_COLUMN].Value.ToString());

        // statistics
        var tuple = Forum.ParseLink(link);
        if (statistics.ContainsKey(tuple.Item1))
          statistics[tuple.Item1]++;
        else
          statistics[tuple.Item1] = 1;
        bw.ReportProgress(i);
      }
      return statistics;
    }

    /// <summary>
    /// Handle progresschanged event.
    /// </summary>
    /// <param name="progressPercentage">The progress percentage.</param>
    private void doDelete_ProgressChanged(int progressPercentage)
    {
      toolStripProgressBar1.Value = progressPercentage;
    }

    /// <summary>
    /// handle workercompleted event.
    /// </summary>
    /// <param name="statistics">The statistics.</param>
    /// <param name="e">The e.</param>
    private void doDelete_RunWorkerCompleted(Dictionary<string, int> statistics, Exception e)
    {
      // 移除已經刪除掉的列
      List<DataGridViewRow> selectedRows = GetSelectedRows();
      foreach (DataGridViewRow row in selectedRows)
      {
        dataGridView1.Rows.Remove(row);
      }
      dataGridView1.ClearSelection();
      dataGridView1.ResumeLayout();

      // 儲存 spam database 並更新
      spamDatabase.save();
      fillTextSpams();

      StringBuilder sb = new StringBuilder();
      sb.AppendLine("刪除完成!");
      foreach (var key in statistics.Keys)
      {
        sb.AppendLine(String.Format("{0}版有{1}篇垃圾文。", key, statistics[key]));
        if (chkBoxNotice.Checked)
        {
          if (!Forum.PostToBoard(key, string.Format("[{0}]已刪除{1}篇垃圾文。", DateTime.Now.ToShortDateString(), statistics[key])))
            Debug.WriteLine("無法張貼公告!");
        }
      }

      MessageBox.Show(sb.ToString());
      setStatusMessage(String.Format("於 {0} {1} 刪除完成。", DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString()));

      chkBoxNotice.Enabled = true;
      numericUpDown1.Enabled = true;
      btnCheck.Enabled = true;
    }

    private void btnDownload_Click(object sender, EventArgs e)
    {
      MessageBox.Show("現在是空的!");
    }

    private bool checkIECookies()
    {
      webBrowser1.Navigate("http://fox.hanyu.com.tw");
      while (true)
      {
        System.Threading.Thread.Sleep(1000);
        Application.DoEvents();
        if (webBrowser1.ReadyState == WebBrowserReadyState.Complete)
        {
          break;
        }
      }

      string username = webBrowser1.Document.GetElementById("Top_TopList2").Children[0].InnerText;
      if (username == "請先登錄")
      {
        MessageBox.Show("你還沒登入，請先用 IE 登入，並將'Cookie選項'設為'保存一個月'。");
        return false;
      }
      return true;
    }

    private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
      DataGridView dgv = (DataGridView)sender;
      if (dgv.Columns[e.ColumnIndex] is DataGridViewLinkColumn && e.RowIndex != -1)
      {
        Uri uri = (Uri)dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
        toolStripProgressBar1.Value = 0;
        webBrowser1.Navigate(uri);
        tabControl1.SelectedIndex = 1;
      }
    }
  }
}
